#include "FpSubject.h"
#include "FpObserver.h"

FpSubject::FpSubject()
{
	_observerList.clear();
	_observerStrList.clear();
}

void FpSubject::Attach(std::weak_ptr<FpObserver> ob, std::string str/*=""*/)
{
	//_mtxObserver.lock();
	std::lock_guard<std::mutex> locker(_mtxObserver);
	auto it = _observerList.begin();
	while (it != _observerList.end()) {
		if ((*it).lock() == ob.lock())
		{
			return;
		}
		++it;
	}
	_observerList.push_back(ob);
	_observerStrList.push_back(str);
}

void FpSubject::Detach(std::weak_ptr<FpObserver> ob, std::string str /*= ""*/)
{
	std::lock_guard<std::mutex> locker(_mtxObserver);
	for (auto it = _observerList.begin();it != _observerList.end();++it)
	{
		if (it->lock() == ob.lock())
		{
			_observerList.erase(it);
			break;
		}
		if (it == _observerList.end())
		{
			break;
		}
	}
	for (auto it = _observerStrList.begin(); it != _observerStrList.end(); ++it)
	{
		if (*it == str)
		{
			_observerStrList.erase(it);
			break;
		}
		if (it == _observerStrList.end())
		{
			break;
		}
	}

}

void FpSubject::Notify(int status)
{
	std::lock_guard<std::mutex> locker(_mtxObserver);
	auto it = _observerList.begin();
	while (it != _observerList.end()) {
		auto sp = it->lock();
		if (sp)
		{
			sp->Update(status);
			++it;
		}
		else {
			it = _observerList.erase(it);

			if (it == _observerList.end())
			{
				break;
			}
		}
	}
}

void FpSubject::Notify(std::string status)
{
	std::lock_guard<std::mutex> locker(_mtxObserver);
	auto it = _observerList.begin();
	while (it != _observerList.end()) {
		auto sp = it->lock();
		if (sp)
		{
			sp->Update(status.c_str());
			++it;
		}
		else {
			it = _observerList.erase(it);

			if (it == _observerList.end())
			{
				break;
			}
		}
	}
}

void FpSubject::DetachAll()
{
	_observerList.clear();
	_observerStrList.clear();
}
